package com.ktgj.flight.common.hangbanguanjia;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ktgj.common.core.enums.EnumHelper;
import com.ktgj.common.core.exception.ParamException;
import com.ktgj.common.core.utils.*;
import com.ktgj.common.redis.service.RedisService;
import com.ktgj.flight.common.ruili.drdomain.BookingContactInfo;
import com.ktgj.flight.common.hangbanguanjia.domain.*;
import com.ktgj.flight.domain.Airport;
import com.ktgj.flight.domain.InterfaceEntity.*;
import com.ktgj.flight.service.IAirportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class HangBanGuanJiaImpl implements HangBanGuanJia {
    @Autowired
    private RedisService redisService;
    @Autowired
    private IAirportService airportService;

    // 账号
    private final String id = "jinse";

    // 密码
    private final String psd = "18710194469";//"fxjssj123";

    // 下单时预留联系手机号
    private String mobile = "17310645009";

    // 地址
    private final String ip = "http://101.200.123.157:7902/distribution/api/";

    //获取token
    @Override
    public String getToken() {
        String data = redisService.getCacheObject("hangBanGuanJiaToken");
        String url = "";
        String token = "";
        if (data == null || data.equals("")) {
            url = ip + "oauth/token?grant_type=client_credentials&client_id=" + id + "&client_secret=" + psd;
        } else {
            token = data.substring(data.indexOf("\"access_token\":\"") + 16, data.indexOf("\"access_token\":\"") + 16 + 36);
            try {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                if (dateFormat.parse(data.substring(data.indexOf("\"expireTime\":\"") + 14, data.indexOf("\"expireTime\":\"") + 14 + 19)).getTime() <= new Date().getTime()) {
                    url = ip + "oauth/token?grant_type=client_credentials&client_id=" + id + "&client_secret=" + psd + "&refresh_token=" + token;
                }
            } catch (ParseException e) {
                System.out.println("时间转换出错了");
                e.printStackTrace();
            }
        }
        if (!url.equals("")) {
            data = HttpClientUtil.doGet(url);//请求 接口
            HangResponse hangResponse = JSONObject.parseObject(data, HangResponse.class);
            if (hangResponse == null)
            {
                return "";
            }
            if (!hangResponse.msg.equals("success")) {
                throw new ParamException(hangResponse.msg);
            }
            redisService.setCacheObject("hangBanGuanJiaToken", data);//存入新的token
            token = data.substring(data.indexOf("\"access_token\":\"") + 16, data.indexOf("\"access_token\":\"") + 16 + 36);
        }

        return token;
    }

    //查询航班
    @Override
    public MoFlightSearchResponse flightSearch(MoFlightSearchRequest moRequest) {
        MoFlightSearchResponse response = new MoFlightSearchResponse();
        response.OnlyCode = moRequest.OnlyCode;
        response.ProviderCode = moRequest.ProviderCode;
        response.RequestType = moRequest.RequestType;

        String strRequestData = "";
        String strResponseData = "";

        String strUrl = "";
        Map<String, Object> map = new HashMap<>();
        try {
            //指定航班查询
            if (moRequest.GoSearchWhere.ProductId != null && !moRequest.GoSearchWhere.ProductId.equals("")) {
                strUrl = ip + "search/flight/detail?access_token=" + getToken();
                map.put("flightInfoId", moRequest.GoSearchWhere.ProductId);
            }
            //普通航班查询
            else {
                strUrl = ip + "search/flight/list?access_token=" + getToken();
                map.put("depCode", moRequest.GoSearchWhere.OrgAirport);
                map.put("arrCode", moRequest.GoSearchWhere.DstAirport);
                map.put("date", moRequest.GoSearchWhere.DepDate);
                map.put("productType", "pa,pb,pd,pe,pc,ph,pj,pf");
            }
            strRequestData = JSON.toJSONString(map);
            strResponseData = HttpClientUtil.doPostJson(strUrl, strRequestData);
            if (strResponseData == null || strResponseData.equals("")) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "航班查询，未返回数据";
                response.IsSuccess = false;
                return response;
            }
            HangResponse hangResponse = JSONObject.parseObject(strResponseData, HangResponse.class);
            if (!hangResponse.msg.equals("success")) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = hangResponse.msg;
                return response;
            }
            JSONObject jsonObject = (JSONObject) hangResponse.data;
            HangQueryFlight hangQueryFlight = JSON.toJavaObject(jsonObject, HangQueryFlight.class);
            if (hangQueryFlight.status != 0) {
                String msg = "";
                switch (hangQueryFlight.status) {
                    case 3:
                        msg = "无数据返回";
                        break;
                    case 2:
                        msg = "参数错误";
                        break;
                    case 8:
                        msg = "无航线数据";
                        break;
                    default:
                        msg = "未知错误";
                        break;
                }
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = msg;
                response.IsSuccess = false;
                return response;
            }

            //开始解析返回的航班数据
            // 逻辑处理
            // 解析航班
            for (Datas data : hangQueryFlight.datas) {
                FlightInfos nf = data.flightInfo;
                MoFlightInfo finfo = new MoFlightInfo();
                finfo.Airline = nf.acCode;
                finfo.FlightNo = nf.flyNo;
                finfo.PlaneStyle = nf.model;

                finfo.OrgAirport = nf.depCode;
                finfo.DstAirport = nf.arrCode;
                finfo.OrgAirportName = getAirPortNameByRirPortCode(nf.depCode);
                finfo.DstAirportName = getAirPortNameByRirPortCode(nf.arrCode);
                finfo.DepDate = nf.depDateTime;
                finfo.ArrDate = nf.arrDateTime;
                finfo.IsCodeShare = nf.isShare == 1;
                finfo.Carrier = nf.carrierFlyNo;
                finfo.DepTerm = nf.depTerminal;
                finfo.ArrTerm = nf.arrTerminal;

                finfo.ProductIndex = nf.flightInfoId;

                finfo.StopCount = nf.isStop;

                long diff = nf.arrDateTime.getTime() - nf.depDateTime.getTime();
                long diffMinutes = diff / (60 * 1000) % 60;
                long diffHours = diff / (60 * 60 * 1000) % 24;

                String flightTimes = "";
                if (diffHours == 0) {
                    flightTimes = diffMinutes + "分钟";
                } else if (diffMinutes == 0) {
                    flightTimes = diffHours + "小时";
                } else if (diffHours != 0 && diffMinutes != 0) {
                    flightTimes = diffHours + "小时" + diffMinutes + "分钟";
                }
                finfo.flightTimes = flightTimes;

                //finfo.PunctualityRate = decimal.Parse(nf.punctualityInfo.punctualityRate.ToString());

                //解析经停信息
                if (nf.stops != null) {
                    for (Stop stop : nf.stops) {
                        FlightStopEntity Fst = new FlightStopEntity();

                        Fst.ArriveTime = stop.arrDateTime;
                        Fst.DepartTime = stop.depDateTime;
                        Fst.Duration = (int) (Fst.DepartTime.getTime() - Fst.ArriveTime.getTime()) / 1000 / 60;
                        Fst.StopCityCode = stop.airportCode;
                        finfo.ListFlightStop.add(Fst);
                    }
                }

                for (CabinInfos c : data.cabinInfos) {
                    if (c.saleControls != null) continue; //屏蔽有各种限制的票

                    MoCabinInfo cinfo = new MoCabinInfo();
                    cinfo.BaseDisCountRate = new BigDecimal(new Double(c.discount).toString());
                    cinfo.CallCenterAmountInfo.OrgTicketAmount = new BigDecimal(new Double(c.adtPrice.price).toString());
                    if (c.adtPrice.rule != null)
                        if (c.adtPrice.rule.handBaggageRule != null || c.adtPrice.rule.consignBaggageRule != null)
                            cinfo.CabinRule.Baggage = c.adtPrice.rule.handBaggageRule.txt + ";" + c.adtPrice.rule.consignBaggageRule.txt;

                    cinfo.CallCenterAmountInfo.TicketAmount = new BigDecimal(new Double(c.adtPrice.ticketPrice).toString());

                    cinfo.CabinRule.Sign = "以航空公司为准";// c.endorsementcondition;
                    cinfo.CabinRule.Refund = "以航空公司为准";//  c.refundcondition;
                    cinfo.CabinRule.Change = "以航空公司为准";// c.reroutecondition;

                    /*if (c.baseCabin == "Y") cinfo.CabinLevel = 3;
                    if (c.baseCabin == "C" || c.baseCabin == "J") cinfo.CabinLevel = 2;
                    if (c.baseCabin == "F") cinfo.CabinLevel = 1;*/

                    if (c.baseCabin.equals("Y")) {
                        cinfo.BaseCabin = "Y";
                        cinfo.BaseCabinName = "经济舱";
                    }
                    if (c.baseCabin.equals("C")) {
                        cinfo.BaseCabin = "C";
                        cinfo.BaseCabinName = "公务舱";
                    }
                    if (c.baseCabin.equals("J")) {
                        cinfo.BaseCabin = "J";
                        cinfo.BaseCabinName = "公务舱";
                    }
                    if (c.baseCabin.equals("F")) {
                        cinfo.BaseCabin = "F";
                        cinfo.BaseCabinName = "头等舱";
                    }

                    if (c.left > 10) {
                        cinfo.CabinLeftDesc = "座位充足";
                    } else {
                        cinfo.CabinLeftDesc = String.valueOf(c.left);
                    }

                    finfo.AirportTax = BigDecimal.valueOf(c.adtPrice.airportFee);
                    finfo.FuelTax = BigDecimal.valueOf(c.adtPrice.oilFee);

                    cinfo.Cabin = c.adtPrice.cabin;
                    if (c.voucher == 0) cinfo.IsFullReceipt = true;

                    cinfo.CabinLeft = c.left;

                    cinfo.ProductPolicy.PolicyId = c.priceInfoId;
                    cinfo.ProductPolicy.StrProductType = c.adtPrice.productType;
                    if (nf.meal == 0) {
                        cinfo.Meal = "无餐食";
                    } else if (nf.meal == 1) {
                        cinfo.Meal = "有餐食";
                    } else if (nf.meal == 2) {
                        cinfo.Meal = "有饮料";
                    } else if (nf.meal == 3) {
                        cinfo.Meal = "有零食";
                    } else if (nf.meal == 4) {
                        cinfo.Meal = "正餐";
                    } else if (nf.meal == 5) {
                        cinfo.Meal = "早餐";
                    } else if (nf.meal == 6) {
                        cinfo.Meal = "午餐";
                    } else if (nf.meal == 7) {
                        cinfo.Meal = "晚餐";
                    } else if (nf.meal == 8) {
                        cinfo.Meal = "点心餐";
                    } else if (nf.meal == 9) {
                        cinfo.Meal = "简餐";
                    } else if (nf.meal == 999) {
                        cinfo.Meal = "餐食以实际为准";
                    }

                    finfo.ListCabinInfo.add(cinfo);

                }
                //添加航班节点
                response.ListGoFlightInfo.add(finfo);

            }
            for (MoFlightInfo item : response.ListGoFlightInfo) {
                MoCabinInfo moCabinInfo;//定义一个临时变量
                for (int i = 0; i < item.ListCabinInfo.size() - 1; i++) {//冒泡趟数
                    for (int j = 0; j < item.ListCabinInfo.size() - i - 1; j++) {
                        if (item.ListCabinInfo.get(j + 1).CallCenterAmountInfo.OrgTicketAmount.compareTo(item.ListCabinInfo.get(j).CallCenterAmountInfo.OrgTicketAmount) == -1) {
                            moCabinInfo = item.ListCabinInfo.get(j);
                            item.ListCabinInfo.set(j, item.ListCabinInfo.get(j + 1));
                            item.ListCabinInfo.set(j + 1, moCabinInfo);
                        }
                    }
                }
            }

            MoFlightInfo MoFlightInfo;//定义一个临时变量
            for (int i = 0; i < response.ListGoFlightInfo.size() - 1; i++) {//冒泡趟数
                for (int j = 0; j < response.ListGoFlightInfo.size() - i - 1; j++) {
                    if (response.ListGoFlightInfo.get(j + 1).ListCabinInfo.size() > 0)
                        if (response.ListGoFlightInfo.get(j + 1).ListCabinInfo.get(0).CallCenterAmountInfo.OrgTicketAmount.compareTo(response.ListGoFlightInfo.get(j).ListCabinInfo.get(0).CallCenterAmountInfo.OrgTicketAmount) == -1) {
                            MoFlightInfo = response.ListGoFlightInfo.get(j);
                            response.ListGoFlightInfo.set(j, response.ListGoFlightInfo.get(j + 1));
                            response.ListGoFlightInfo.set(j + 1, MoFlightInfo);
                        }
                }
            }

            response.IsSuccess = true;
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }
        return response;
    }

    //验舱验价
    @Override
    public MoFlightCheckResponse flightCheck(MoFlightCheckRequest moRequest) {
        MoFlightCheckResponse response = new MoFlightCheckResponse();
        response.OnlyCode = moRequest.OnlyCode;
        response.ProviderCode = moRequest.ProviderCode;
        response.RequestType = moRequest.RequestType;

        String strRequestData = "";
        String strResponseData = "";
        String ServerUrl = "";
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        try {
            //先调用指定航班查询接口
            MoFlightSearchRequest hbReq = new MoFlightSearchRequest();
            hbReq.GoSearchWhere = new MoFlightSearchWhere();
            hbReq.GoSearchWhere.ProductId = moRequest.FlightId;
            hbReq.GoSearchWhere.OrgAirport = moRequest.OrgAirport;
            hbReq.GoSearchWhere.DstAirport = moRequest.DstAirport;
            hbReq.GoSearchWhere.DepDate = moRequest.DepDate;
            hbReq.OnlyCode = moRequest.OnlyCode;
            MoFlightSearchResponse hbRes = flightSearch(hbReq);

            if (!hbRes.IsSuccess) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "指定航班接口调用失败,请重新查询";
                response.IsSuccess = false;
                return response;
            }
            MoFlightInfo ff = new MoFlightInfo();
            MoCabinInfo cc = new MoCabinInfo();

            String flightInfoId = "";
            String priceInfoId = "";
            String prdSubType = "";
            boolean isexists = false;
            for (MoFlightInfo f : hbRes.ListGoFlightInfo) {
                if (!f.FlightNo.equals(moRequest.FlightNo) || !f.OrgAirport.equals(moRequest.OrgAirport) || !f.DstAirport.equals(moRequest.DstAirport) ||
                        !dateFormat.format(f.DepDate).equals(moRequest.DepDate)) continue;
                for (MoCabinInfo c : f.ListCabinInfo) {
                    if (!c.ProductPolicy.StrProductType.equals(moRequest.ProductType) || c.CallCenterAmountInfo.OrgTicketAmount.compareTo(moRequest.Price) == 1)
                        continue;

                    ff = f;
                    cc = c;

                    flightInfoId = f.ProductIndex;
                    priceInfoId = c.ProductPolicy.PolicyId;
                    prdSubType = c.ProductPolicy.StrProductType;

                    isexists = true;
                    break;
                }
            }

            if (!isexists) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "舱位已售完,请重新查询航班";
                response.IsSuccess = false;
                return response;
            }

            ServerUrl = ip + "order/per/cabin/confirm?access_token=" + getToken();

            Map<String, Object> map = new HashMap<>();
            Map<String, Object> map1 = new HashMap<>();
            List<Map<String, Object>> ticketTokens = new ArrayList<>();

            map1.put("flightInfoId", flightInfoId);
            map1.put("priceInfoId", priceInfoId);
            map1.put("productType", prdSubType);
            ticketTokens.add(map1);

            map.put("tripType", "OW");
            map.put("ticketTokens", ticketTokens);
            map.put("adultNum", "1");
            map.put("childNum", "0");

            strRequestData = JSON.toJSONString(map);

            strResponseData = HttpClientUtil.doPostJson(ServerUrl, strRequestData);

            if (strResponseData == null || strResponseData.equals("")) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "舱位验价，未返回数据";
                response.IsSuccess = false;
                return response;
            }

            // 验价实体处理
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);
            if (!fsResponse.msg.equals("success")) {
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                response.ErrorMsg = fsResponse.msg;
                response.IsSuccess = false;
                return response;
            }

            // 验舱和验价需要同时通过才能继续下单    isFull=false 就表示验舱通过   如果flightCheckResult有返回值  可以验证下剩余舱位数  如果未返回  就放过
            //判断验仓是否通过
            JSONObject jsonObject = (JSONObject) fsResponse.data;
            HangPriceConfirm hangQueryFlight = JSON.toJavaObject(jsonObject, HangPriceConfirm.class);

            Seats seat = hangQueryFlight.selectCabin.adtPrice.seats.get(0);
            if (seat.left <= 0) {
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                response.ErrorMsg = "舱位已售完！";
                response.IsSuccess = false;
                return response;
            } else {
                response.SeatCount = seat.left;
            }

            //判断验价是否通过
            CabinPrice price = hangQueryFlight.selectCabin.adtPrice;
            if (price.price + price.airportFee + price.oilFee != moRequest.Price.doubleValue()) {
                response.ErrorMsg = "价格不符,请重新查询";
                response.IsSuccess = false;
                return response;
            } else {
                response.TicketAmount = new BigDecimal(new Double(price.fare).toString());
                response.AirportTax = new BigDecimal(new Double(price.airportFee).toString());
                response.FuelTax = new BigDecimal(new Double(price.oilFee).toString());

                response.PolicyID = hangQueryFlight.context;
            }

            if (price.fare + price.airportFee + price.oilFee == moRequest.Price.doubleValue() && response.SeatCount > 0)
                response.IsSuccess = true;

        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }

        return response;
    }

    //查询往返航班列表
    @Override
    public HangResponse getRTFlight(Map<String, Object> map) {
        HangResponse hangResponse = postHangResponse(ip + "search/flight/rt/list?access_token=" + getToken(), JSON.toJSONString(map));

        JSONObject jsonObject = (JSONObject) hangResponse.data;
        HangQueryFlight hangQueryFlight = JSON.toJavaObject(jsonObject, HangQueryFlight.class);/** 用的时候这么转，你学会了吗？？？？？ */

        return hangResponse;
    }

    //查询指定往返航班
    @Override
    public HangResponse getRTFlightDetail(Map<String, Object> map) {
        HangResponse hangResponse = postHangResponse(ip + "search/flight/rt/detail?access_token=" + getToken(), JSON.toJSONString(map));

        JSONObject jsonObject = (JSONObject) hangResponse.data;
        HangQueryFlight hangQueryFlight = JSON.toJavaObject(jsonObject, HangQueryFlight.class);/** 用的时候这么转，你学会了吗？？？？？ */

        return hangResponse;
    }

    //提交订单
    @Override
    public MoCreateOrderResponse orderCreate(MoCreateOrderRequest request) {
        MoCreateOrderResponse response = new MoCreateOrderResponse();

        response.RequestType = EnumHelper.RequestType.HangBanGuanJia;
        response.OnlyCode = request.OnlyCode;

        String strRequestData = "";
        String strResponseData = "";

        String strUrl = "";

        try {
            strUrl = ip + "order/submit?access_token=" + getToken();

            Map<String, Object> map = new HashMap<>();

            map.put("contactEmail", BookingContactInfo.Email);
            map.put("contactPhone", BookingContactInfo.MobilePhone);
            map.put("context", request.PolicyID);

            List<Map<String, Object>> passengers = new ArrayList<>();
            for (MoPassenger p : request.ListMoPassenger) {
                Map<String, Object> passenger = new HashMap<>();
                passenger.put("name", p.PassengerName);
                passenger.put("idType", getIdType(p.IDType));
                passenger.put("type", "ADT");
                passenger.put("idCard", p.IDNO);
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                passenger.put("birthday", dateFormat.format(p.Birthday));
                passenger.put("phone", p.PassengerMobile);
                String gender = "1";
                if (p.IDType == 1 && "2,4,6,8,0".indexOf(p.IDNO.substring(16, 17)) >= 0) {
                    gender = "2";
                }
                passenger.put("gender", gender);
                passenger.put("countryType", "domestic");

                //passenger.put("phoneCode", "");
                passengers.add(passenger);
            }
            map.put("passengers", passengers);
            strRequestData = JSON.toJSONString(map);

            strResponseData = HttpClientUtil.doPostJson(strUrl, strRequestData);

            if (strResponseData == null || strResponseData.equals("")) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "创建订单接口，未返回数据";
                response.IsSuccess = false;
                return response;
            }

            // 验价实体处理
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);
            if (!fsResponse.msg.equals("success")) {
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                response.ErrorMsg = fsResponse.msg;
                response.IsSuccess = false;
                return response;
            }
            JSONObject jsonObject = (JSONObject) fsResponse.data;
            HangOrder hangOrder = JSON.toJavaObject(jsonObject, HangOrder.class);

            response.MainOrderID = hangOrder.orderId;
            response.ExternalNo = hangOrder.payOrderId;

            if (response.MainOrderID != null && !response.MainOrderID.equals("")) {
                response.IsSuccess = true;
            }
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }

        return response;
    }

    /// 转换证件号码
    private int getIdType(int IdType) {
        // { 无证件 = 0, 身份证 = 1, 军人证 = 2, 学生证 = 3, 护照 = 4, 港澳居民来往内地通行证 = 5, 其他证 = 6,
        // 台湾居民来往大陆通行证 = 7, 驾驶证 = 8, 港澳通行证 = 9, 户口本 = 10, 出生证明 = 11, 台湾通行证 = 12,永久居留身份证=13, 其他证件 = 99 }

        switch (IdType) {
            case 1:
                return 0;
            case 4:
                return 1;
            case 99:
                return 2;
            case 10:
                return 2;
            case 6:
                return 2;
            case 5:
                return 3;
            case 2:
                return 4;
            case 9:
                return 6;
            case 7:
                return 7;
            case 12:
                return 8;
            case 13:
                return 9;


            case 11:
                return 13;
            default:
                return 2;
        }
    }

    //取消订单
    @Override
    public MoCancelOrderResponse cancelOrder(MoCancelOrderRequest request) {
        MoCancelOrderResponse response = new MoCancelOrderResponse();
        response.RequestType = EnumHelper.RequestType.HangBanGuanJia;
        response.OnlyCode = request.OnlyCode;

        String strRequestData = "";
        String strResponseData = "";
        String url = "";
        try {
            if (StringUtils.isEmpty(request.ListOrderItem.OrderID)) {
                response.ErrorMsg = EnumHelper.ReturnCode.请求参数为空.toString();
                response.ErrorCode = 10007 + "";
                return response;
            }
            url = ip + "order/cancel?access_token=" + getToken();

            Map<String, Object> map = new HashMap<>();
            map.put("orderId", request.ListOrderItem.OrderID);
            strRequestData = JSON.toJSONString(map);

            strResponseData = HttpClientUtil.doPostJson(url, strRequestData);
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);

            if (fsResponse.code != 1) {
                response.ErrorMsg = fsResponse.msg;
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }

            response.IsSuccess = true;
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }
        return response;
    }

    //查询订单详情
    @Override
    public MoQueryOrderResponse queryOrderInfo(MoQueryOrderRequest request) {
        MoQueryOrderResponse response = new MoQueryOrderResponse();
        response.RequestType = EnumHelper.RequestType.HangBanGuanJia;
        response.OnlyCode = request.OnlyCode;

        String strRequestData = "";
        String strResponseData = "";

        String url = "";
        try {
            if (request.OrderID == null || request.OrderID.equals("")) {
                response.ErrorMsg = EnumHelper.ReturnCode.请求参数为空.toString();
                response.ErrorCode = 10007 + "";
                return response;
            }
            url = ip + "order/detail?access_token=" + getToken();

            Map<String, Object> map = new HashMap<>();
            map.put("orderId", request.OrderID);

            strRequestData = JSON.toJSONString(map);

            strResponseData = HttpClientUtil.doPostJson(url, strRequestData);
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);

            if (fsResponse.code != 1) {
                response.ErrorMsg = fsResponse.msg;
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }
            //开始赋值
            JSONObject jsonObject = (JSONObject) fsResponse.data;
            HangOrder d = JSON.toJavaObject(jsonObject, HangOrder.class);
            response.Amount = new BigDecimal(new Double(d.totalPrice).toString());
            response.OrderID = d.orderId;
            //订单状态：1：等待付款，2：⽀付待确认 3：已取消 4：
            //出票中 5：已出票 6：改升中 7：已改升 8：退票中 9：已退票
            if (d.orderStatus == 1)
                response.OrderStatus = EnumHelper.OrderStatus.下单成功等待支付.getValue();
            if (d.orderStatus == 2)
                response.OrderStatus = EnumHelper.OrderStatus.支付成功等待出票.getValue();
            if (d.orderStatus == 3)
                response.OrderStatus = EnumHelper.OrderStatus.订单取消.getValue();
            if (d.orderStatus == 4)
                response.OrderStatus = EnumHelper.OrderStatus.出票中.getValue();
            if (d.orderStatus == 5)
                response.OrderStatus = EnumHelper.OrderStatus.出票完成.getValue();
            if (d.orderStatus == 6)
                response.OrderStatus = EnumHelper.OrderStatus.改期申请.getValue();
            if (d.orderStatus == 7)
                response.OrderStatus = EnumHelper.OrderStatus.改期成功.getValue();
            if (d.orderStatus == 8)
                response.OrderStatus = EnumHelper.OrderStatus.退票申请.getValue();
            if (d.orderStatus == 9)
                response.OrderStatus = EnumHelper.OrderStatus.退票完成等待退款.getValue();
            if (d.orderStatus == 10)
                response.OrderStatus = EnumHelper.OrderStatus.已使用.getValue();

            if (d.tripType == "OW")
                response.TripType = EnumHelper.TripType.单程.getValue();
            response.Contacts.ContactMobile = d.contactPhone;
            response.Contacts.ContactName = d.contactName;

            //行程信息
            for (Segments sg : d.segments) {
                MoSegment seg = new MoSegment();
                seg.Airline = sg.acCode;
                seg.FlightNo = sg.flyNo;
                seg.OrgAirport = sg.depCode;
                seg.DstAirport = sg.arrCode;

                seg.DepDate = sg.depDateTime;
                seg.ArrDate = sg.arrDateTime;

                seg.Cabin = sg.cabin;

                //乘客信息
                for (Passenger p : sg.passengers) {
                    if (p.rule != null)
                        seg.rule = "退票条件:" + p.rule.refundRule + ";更改条件:" + p.rule.changeRule + ";签转条件:" + p.rule.transferRule + ";手提行李规则:" + p.rule.handBaggageRule.txt + ";托运行李规则" + p.rule.consignBaggageRule.txt;
                    MoPassenger psg = new MoPassenger();
                    psg.PassengerName = p.name;
                    psg.IDType = getIdType(p.idType);
                    psg.IDNO = p.idCard;

                    psg.PassengerMobile = p.phone;
                    psg.Birthday = p.birthday;
                    psg.Sex = p.sex == 1 ? true : false;
                    psg.PsgID = p.ticketId + "";
                    psg.PNR = p.pnr;
                    psg.TicketAmount = new BigDecimal(new Double(p.price).toString());
                    psg.AirportTax = new BigDecimal(new Double(p.airportFee).toString());
                    psg.FuelTax = new BigDecimal(new Double(p.oilFee).toString());

                    psg.TicketNo = p.eticket;
                    //机票状态
                    //1：待出票 11：已取消
                    //2：已出票 21：出票中 22：出票失败
                    //3：已改期 31：改期中 32：改期失败
                    //4：已退票 41：退票中 42：退票失败
                    //5：已使用
                    if (p.status == 1)
                        psg.Status = EnumHelper.OrderStatus.下单成功等待支付.getValue();
                    if (p.status == 2)
                        psg.Status = EnumHelper.OrderStatus.出票完成.getValue();
                    if (p.status == 3)
                        psg.Status = EnumHelper.OrderStatus.改期成功.getValue();
                    if (p.status == 4)
                        psg.Status = EnumHelper.OrderStatus.退款完成.getValue();
                    if (p.status == 5)
                        psg.Status = EnumHelper.OrderStatus.已使用.getValue();
                    if (p.status == 11)
                        psg.Status = EnumHelper.OrderStatus.订单取消.getValue();
                    if (p.status == 21)
                        psg.Status = EnumHelper.OrderStatus.出票中.getValue();
                    if (p.status == 31)
                        psg.Status = EnumHelper.OrderStatus.改期申请.getValue();
                    if (p.status == 41)
                        psg.Status = EnumHelper.OrderStatus.退票申请.getValue();
                    if (p.status == 22)
                        psg.Status = EnumHelper.OrderStatus.出票失败.getValue();
                    if (p.status == 32)
                        psg.Status = EnumHelper.OrderStatus.改期失败.getValue();
                    if (p.status == 42)
                        psg.Status = EnumHelper.OrderStatus.退票失败.getValue();


                    response.ListMoPassenger.add(psg);
                }
                response.ListGoSegment.add(seg);
            }
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (d.expectTicketTime != null && !d.expectTicketTime.equals(""))
                response.IssDateLimit = dateFormat.parse(d.expectTicketTime);
            if (d.tradeInfo != null && d.tradeInfo.tradeDetails != null && d.tradeInfo.tradeDetails.size() > 0) {
                for (TradeDetails tade : d.tradeInfo.tradeDetails) {
                    if (tade.selfTradeNo == null || tade.selfTradeNo.equals("")) continue;
                    MoPayInfo pay = new MoPayInfo();
                    pay.TradeId = tade.selfTradeNo;
                    response.ListPayInfo.add(pay);
                }
            }
            response.IsSuccess = true;
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }
        return response;
    }

    //出票前确认
    @Override
    public MoOrderCheckResponse orderCheck(MoOrderCheckRequest request) {
        MoOrderCheckResponse response = new MoOrderCheckResponse();
        response.RequestType = EnumHelper.RequestType.HangBanGuanJia;
        response.OnlyCode = request.OnlyCode;

        String strRequestData = "";
        String strResponseData = "";
        String url = "";
        try {
            url = ip + "order/confirm?access_token=" + getToken();

            Map<String, Object> map = new HashMap<>();
            map.put("orderId", request.OrderID);

            strRequestData = JSON.toJSONString(map);

            strResponseData = HttpClientUtil.doPostJson(url, strRequestData);
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);

            if (fsResponse.code != 1) {
                response.ErrorMsg = fsResponse.msg;
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }

            JSONObject jsonObject = (JSONObject) fsResponse.data;
            HangOrderConfirm hangOrderConfirm = JSON.toJavaObject(jsonObject, HangOrderConfirm.class);

            if (hangOrderConfirm.canPay == 0) {
                response.ErrorMsg = "正在帮您申请座位,请您5秒后再点击此按钮";
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }
            if (hangOrderConfirm.canPay == -1) {
                response.ErrorMsg = "非常抱歉,没能帮您申请到此价格，请您取消订单重新查询预订";
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }

            response.ExpireTime = hangOrderConfirm.expireTime;
            if (response.ExpireTime.before(new Date())) {
                response.ErrorMsg = "已超过最晚支付时间,当前订单已不可支付";
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }
            response.PayAmount = new BigDecimal(new Double(hangOrderConfirm.feeDetail.totalPayPrice).toString());

            response.IsSuccess = true;

        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }
        return response;
    }

    //提交出票(改期)
    @Override
    public MoOrderPayResponse orderPay(MoOrderPayRequest request) {
        MoOrderPayResponse response = new MoOrderPayResponse();
        response.RequestType = EnumHelper.RequestType.HangBanGuanJia;
        response.OnlyCode = request.OnlyCode;

        String strRequestData = "";
        String strResponseData = "";
        String url = "";
        try {
            url = ip + "order/issue?access_token=" + getToken();

            Map<String, Object> map = new HashMap<>();
            map.put("orderId", request.MainOutOrderID);

            strRequestData = JSON.toJSONString(map);

            strResponseData = HttpClientUtil.doPostJson(url, strRequestData);
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);

            if (fsResponse.code != 1) {
                response.ErrorMsg = EnumHelper.ReturnCode.失败.toString();
                response.ErrorCode = fsResponse.msg;
                return response;
            }

            MoQueryOrderRequest qreq = new MoQueryOrderRequest();
            qreq.OnlyCode = request.OnlyCode;
            qreq.OrderID = request.MainOutOrderID;
            qreq.RequestType = request.RequestType;
            MoQueryOrderResponse qres = queryOrderInfo(qreq);
            if (qres.IsSuccess && qres.ListPayInfo != null && qres.ListPayInfo.size() > 0) {
                response.PayInfo.TradeId = qres.ListPayInfo.get(0).TradeId;
            }

            JSONObject jsonObject = (JSONObject) fsResponse.data;
            HangOrder hangOrder = JSON.toJavaObject(jsonObject, HangOrder.class);

            response.PayInfo.SwiftNumber = hangOrder.payOrderId;

            response.IsSuccess = true;
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }
        return response;
    }

    //查询退改规则
    @Override
    public HangResponse ticketRule(Map<String, Object> map) {
        HangResponse hangResponse = postHangResponse(ip + "order/ticket/rule?access_token=" + getToken(), JSON.toJSONString(map));

        JSONArray jsonArray = (JSONArray) hangResponse.data;
        List<Rule> rule = jsonArray.toJavaList(Rule.class);/** 用的时候这么转，你学会了吗？？？？？ */

        return hangResponse;
    }

    //查询退改手续费
    @Override
    public MoOrderRefundCaltResponse orderRefundCalt(MoOrderRefundCaltRequest request) {
        MoOrderRefundCaltResponse response = new MoOrderRefundCaltResponse();
        response.RequestType = EnumHelper.RequestType.HangBanGuanJia;
        response.OnlyCode = request.OnlyCode;

        String strRequestData = "";
        String strResponseData = "";
        String url = "";
        try {
            MoQueryOrderRequest request1 = new MoQueryOrderRequest();
            request1.OnlyCode = request.OnlyCode;
            request1.OrderID = request.OutOrderID;
            MoQueryOrderResponse detial = queryOrderInfo(request1);
            if (!detial.IsSuccess) {
                response.ErrorMsg = detial.ErrorMsg;
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }

            for (MoPassenger r : request.ListMoPassenger) {
                MoPassenger p = detial.ListMoPassenger.stream().filter(item -> item.PassengerName.equals(r.PassengerName) && item.IDNO.equals(r.IDNO)).findFirst().orElse(null);
                if (p == null) {
                    response.ErrorMsg = "未找到 " + r.PassengerName + " 的乘客ID";
                    response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                    return response;
                }

                r.PsgID = p.PsgID;
            }
            String strPsgId = "";
            for (MoPassenger p : request.ListMoPassenger)
                strPsgId += p.PsgID + ",";
            strPsgId = strPsgId.substring(0, strPsgId.length() - 1);

            url = ip + "order/ticket/rule/fee?access_token=" + getToken();

            Map<String, Object> map = new HashMap<>();
            map.put("orderId", request.OutOrderID);
            map.put("ticketIds", strPsgId);
            map.put("applyType", request.RefundType <= 1 ? 0 : 1);
            map.put("queryType", 0);

            strRequestData = JSON.toJSONString(map);

            strResponseData = HttpClientUtil.doPostJson(url, strRequestData);
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);

            if (fsResponse.code != 1) {
                response.ErrorMsg = fsResponse.msg;
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }

            JSONObject jsonObject = (JSONObject) fsResponse.data;
            HangTicketRuleFee hangTicketRuleFee = JSON.toJavaObject(jsonObject, HangTicketRuleFee.class);

            response.OutOrderID = hangTicketRuleFee.orderId;
            response.RefundFee = new BigDecimal(new Double(hangTicketRuleFee.totalFee).toString());

            for (MoPassenger p : request.ListMoPassenger) {
                Tickets op = hangTicketRuleFee.tickets.stream().filter(item -> item.ticketId == Integer.valueOf(p.PsgID).intValue()).findFirst().orElse(null);

                if (op == null) {
                    response.ErrorMsg = "未找到 " + p.PassengerName + " 的退票信息";
                    response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                    return response;
                }

                p.RefundFee = new BigDecimal(new Double(op.fee).toString());

                response.ListRefundPassenger.add(p);
            }
            response.IsSuccess = true;
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }
        return response;
    }

    //提交退票申请
    @Override
    public MoOrderRefundResponse orderRefund(MoOrderRefundRequest request) {
        MoOrderRefundResponse response = new MoOrderRefundResponse();
        response.RequestType = EnumHelper.RequestType.HangBanGuanJia;
        response.OnlyCode = request.OnlyCode;

        String strRequestData = "";
        String strResponseData = "";
        String url = "";
        try {
            String strPsgId = "";

            for (MoPassenger p : request.ListMoPassenger)
                strPsgId += p.PsgID + ",";
            strPsgId = strPsgId.substring(0, strPsgId.length() - 1);

            //如果有材料证明，先调用材料证明上传接口
            /*if (request.ListAttachment != null && request.ListAttachment.size() > 0)
            {
                MoAttachmentRequest attRequest = new MoAttachmentRequest();
                attRequest.ApplyId = strPsgId;
                attRequest.ApplyType = 0;
                attRequest.OrderId = request.OrderID;
                attRequest.ListMoFile = new ArrayList<>();
                for (Attachment at : request.ListAttachment)
                {
                    MoFile mf = new MoFile();
                    mf.AttachmentId = at.ID;
                    mf.Content = new byte[at.Content.length];
                    for (int i = 0; i < at.Content.length; i++) {
                        mf.Content[i] = at.Content[i].byteValue();
                    }
                    mf.Name = at.Name;
                    attRequest.ListMoFile.add(mf);
                }

                MoAttachmentResponse attResponse = _AddAttachment(attRequest);
                if (!attResponse.IsSuccess)
                {
                    response.ErrorMsg = "调用附件上传接口失败：" + attResponse.ErrorMsg;
                    return response;
                }
            }*/

            //验证手续费有没有变更
            MoOrderRefundCaltRequest calt = new MoOrderRefundCaltRequest();
            for (MoPassenger p : request.ListMoPassenger) {
                MoPassenger mp = new MoPassenger();
                mp.IDNO = p.IDNO;
                mp.PassengerName = p.PassengerName;
                calt.ListMoPassenger.add(mp);
            }

            calt.OutOrderID = request.OrderID;
            calt.RefundType = request.RefundType;
            MoOrderRefundCaltResponse caltRes = orderRefundCalt(calt);
            for (MoPassenger cp : caltRes.ListRefundPassenger) {
                MoPassenger p = request.ListMoPassenger.stream().filter(item -> item.PassengerName.equals(cp.PassengerName) && item.IDNO.equals(cp.IDNO)).findFirst().orElse(null);
                if (p == null) {
                    response.ErrorMsg = "查询退票费接口调用失败" + caltRes.ErrorMsg;
                    return response;
                }
                if (p.RefundFee != cp.RefundFee) {
                    response.ErrorMsg = "乘客 " + p.PassengerName + " 的退票费已经由 " + p.RefundFee + " 元变为 " + cp.RefundFee + " 元，请重新发B单";
                    return response;
                }
            }

            MoQueryOrderRequest mqo = new MoQueryOrderRequest();
            mqo.OnlyCode = request.OnlyCode;
            mqo.OrderID = request.OrderID;
            MoQueryOrderResponse detial = queryOrderInfo(mqo);
            if (!detial.IsSuccess) {
                response.ErrorMsg = detial.ErrorMsg;
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }

            for (MoPassenger r : request.ListMoPassenger) {
                MoPassenger p = detial.ListMoPassenger.stream().filter(item -> item.PassengerName.equals(r.PassengerName) && item.IDNO.equals(r.IDNO)).findFirst().orElse(null);
                if (p == null) {
                    response.ErrorMsg = "未找到 " + r.PassengerName + " 的乘客ID";
                    response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                    return response;
                }
                r.PsgID = p.PsgID;
            }

            url = ip + "order/refund/submit?access_token=" + getToken();

            Map<String, Object> req = new HashMap<>();
            req.put("orderId", request.OrderID);

            if (request.RefundType == EnumHelper.RefundType.自愿.getValue()) {
                req.put("applyType", 0);
                req.put("reason", "由于自身原因无法成行,同意扣除退票手续费退票");
            } else {
                req.put("applyType", 1);
                if (request.RefundType == EnumHelper.RefundType.重购全退.getValue()) {
                    req.put("reason", "重购相同客票且已使用,申请全额退票");
                } else if (request.RefundType == EnumHelper.RefundType.病退.getValue()) {
                    req.put("reason", "由于乘机人因病(身故),无法成行,申请全额退票");
                } else if (request.RefundType == EnumHelper.RefundType.其他非自愿.getValue()) {
                    req.put("reason", "其他(拒签、系统问题)");
                } else if (request.RefundType == EnumHelper.RefundType.航变.getValue()) {
                    req.put("reason", "由于航空公司原因,无法成行,申请全额退票");
                }

            }

            List<Map<String, Object>> ticketInfo = new ArrayList<>();
            for (MoSegment s : request.ListMoSegment) {
                for (MoPassenger p : request.ListMoPassenger) {
                    Map<String, Object> ticketInfoMap = new HashMap<>();
                    Map<String, Object> seg = new HashMap<>();

                    seg.put("depCode", s.OrgAirport);
                    seg.put("arrCode", s.DstAirport);
                    seg.put("flyNo", s.FlightNo);

                    ticketInfoMap.put("segment", seg);

                    Map<String, Object> psg = new HashMap<>();

                    psg.put("name", p.PassengerName);
                    psg.put("idCard", p.IDNO);
                    psg.put("idType", getIdType(p.IDType));
                    ticketInfoMap.put("passenger", psg);
                    ticketInfoMap.put("ticketId", p.PsgID);

                    ticketInfo.add(ticketInfoMap);
                }

            }
            req.put("ticketInfo", ticketInfo);
            strRequestData = JSON.toJSONString(req);

            strResponseData = HttpClientUtil.doPostJson(url, strRequestData);
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);

            if (fsResponse.code != 1) {
                response.ErrorMsg = fsResponse.msg;
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }
            JSONObject jsonObject = (JSONObject) fsResponse.data;
            response.OrderID = jsonObject.getString("orderId");
            response.RefundOrderID = jsonObject.getString("refundId");

            response.IsSuccess = true;
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }

        return response;
    }

    //查询改期航班列表
    @Override
    public MoFlightSearchResponse searchChangeDateFlightInfo(MoRescheduleSearchRequest moRequest) {
        MoFlightSearchResponse response = new MoFlightSearchResponse();
        response.OnlyCode = moRequest.OnlyCode;
        response.ProviderCode = moRequest.ProviderCode;
        response.RequestType = moRequest.RequestType;

        String strRequestData = "";
        String strResponseData = "";

        String strUrl = "";
        try {
            strUrl = ip + "order/change/flight/list?access_token=" + getToken();

            String strPsgId = "";
            for (ChangePassenger p : moRequest.ListChangePassenger)
                strPsgId += p.Id + ",";
            strPsgId = strPsgId.substring(0, strPsgId.length() - 1);

            Map<String, Object> requstHeadBody = new HashMap<>();

            requstHeadBody.put("orderId", moRequest.OrderID);
            requstHeadBody.put("ticketIds", strPsgId);
            requstHeadBody.put("depCode", moRequest.DCity);
            requstHeadBody.put("arrCode", moRequest.ACity);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            requstHeadBody.put("date", dateFormat.format(moRequest.DepartDate));

            strRequestData = JSON.toJSONString(requstHeadBody);

            strResponseData = HttpClientUtil.doPostJson(strUrl, strRequestData);
            if (strResponseData == null || strResponseData.equals("")) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "航班查询，未返回数据";
                response.IsSuccess = false;
                return response;
            }

            // 验价实体处理
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);
            if (fsResponse.code != 1) {

                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "航班查询，未成功" + fsResponse.msg;
                response.IsSuccess = false;
                return response;
            }

            JSONObject jsonObject = (JSONObject) fsResponse.data;
            HangChangeConfirm hangChangeFlight = JSON.toJavaObject(jsonObject, HangChangeConfirm.class);

            for (Flights data : hangChangeFlight.flights) {
                FlightInfos nf = data.flightInfos.get(0);
                MoFlightInfo finfo = new MoFlightInfo();
                finfo.Airline = nf.acCode;
                finfo.FlightNo = nf.flyNo;
                finfo.PlaneStyle = nf.model;

                finfo.OrgAirport = nf.depCode;
                finfo.DstAirport = nf.arrCode;
                finfo.DepDate = nf.depDateTime;
                finfo.ArrDate = nf.arrDateTime;
                finfo.IsCodeShare = nf.isShare == 1 ? true : false;
                finfo.Carrier = nf.carrierFlyNo;
                finfo.DepTerm = nf.depTerminal;
                finfo.ArrTerm = nf.arrTerminal;

                finfo.ProductIndex = data.flightInfoId;

                //解析经济舱，公务舱，头等舱的全价
                for (CabinInfos c : data.cabinInfos) {
                    MoCabinInfo cinfo = new MoCabinInfo();

                    cinfo.BaseAmount = new BigDecimal(new Double(c.adtPrice.realPrice).toString());
                    cinfo.CallCenterAmountInfo.OrgTicketAmount = new BigDecimal(new Double(c.adtPrice.realPrice).toString());
                    cinfo.CallCenterAmountInfo.TicketAmount = new BigDecimal(new Double(c.adtPrice.realPrice).toString());

                    cinfo.CabinRule.Sign = c.adtPrice.rule.changeRule;
                    cinfo.CabinRule.Refund = c.adtPrice.rule.refundRule;
                    cinfo.CabinRule.Change = c.adtPrice.rule.transferRule;

                    Seats seat = c.adtPrice.seats.get(0);
                    if (seat.baseCabin == "Y") cinfo.CabinLevel = EnumHelper.CabinLevel.经济舱.getValue();
                    if (seat.baseCabin == "C" || seat.baseCabin == "J")
                        cinfo.CabinLevel = EnumHelper.CabinLevel.公务舱.getValue();
                    if (seat.baseCabin == "F") cinfo.CabinLevel = EnumHelper.CabinLevel.头等舱.getValue();

                    cinfo.BaseCabin = seat.baseCabin;
                    cinfo.Cabin = seat.cabin;
                    cinfo.BaseDisCountRate = new BigDecimal(new Double(seat.discount).toString());
                    cinfo.CabinLeft = seat.left;

                    cinfo.ProductPolicy.PolicyId = c.priceInfoId;


                    finfo.ListCabinInfo.add(cinfo);
                    finfo.AirportTax = new BigDecimal(new Double(c.adtPrice.oilFee).toString());
                    finfo.FuelTax = new BigDecimal(new Double(c.adtPrice.fare).toString());
                }
                //添加航班节点
                response.ListGoFlightInfo.add(finfo);
            }

            for (MoFlightInfo item : response.ListGoFlightInfo) {
                MoCabinInfo moCabinInfo;//定义一个临时变量
                for (int i = 0; i < item.ListCabinInfo.size() - 1; i++) {//冒泡趟数
                    for (int j = 0; j < item.ListCabinInfo.size() - i - 1; j++) {
                        if (item.ListCabinInfo.get(j + 1).CallCenterAmountInfo.OrgTicketAmount.compareTo(item.ListCabinInfo.get(j).CallCenterAmountInfo.OrgTicketAmount) == -1) {
                            moCabinInfo = item.ListCabinInfo.get(j);
                            item.ListCabinInfo.set(j, item.ListCabinInfo.get(j + 1));
                            item.ListCabinInfo.set(j + 1, moCabinInfo);
                        }
                    }
                }
            }

            MoFlightInfo MoFlightInfo;//定义一个临时变量
            for (int i = 0; i < response.ListGoFlightInfo.size() - 1; i++) {//冒泡趟数
                for (int j = 0; j < response.ListGoFlightInfo.size() - i - 1; j++) {
                    if (response.ListGoFlightInfo.get(j + 1).ListCabinInfo.size() > 0)
                        if (response.ListGoFlightInfo.get(j + 1).ListCabinInfo.get(0).CallCenterAmountInfo.OrgTicketAmount.compareTo(response.ListGoFlightInfo.get(j).ListCabinInfo.get(0).CallCenterAmountInfo.OrgTicketAmount) == -1) {
                            MoFlightInfo = response.ListGoFlightInfo.get(j);
                            response.ListGoFlightInfo.set(j, response.ListGoFlightInfo.get(j + 1));
                            response.ListGoFlightInfo.set(j + 1, MoFlightInfo);
                        }
                }
            }
            response.IsSuccess = true;
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }
        return response;
    }

    //改期前确认
    @Override
    public MoChangeConfirmResponse changeConfirm(MoChangeConfirmRequest request) {
        MoChangeConfirmResponse response = new MoChangeConfirmResponse();
        response.RequestType = EnumHelper.RequestType.HangBanGuanJia;
        response.OnlyCode = request.OnlyCode;

        String strRequestData = "";
        String strResponseData = "";
        String url = "";
        try {
            url = ip + "order/change/confirm?access_token=" + getToken();

            Map<String, Object> req = new HashMap<>();
            req.put("tripType", "OW");
            req.put("orderId", request.orderId);
            req.put("baseCabin", request.baseCabin);
            req.put("cabin", request.cabin);
            req.put("ticketIds", request.ticketIds);
            if (request.changeType == EnumHelper.RefundType.自愿.getValue()) {
                req.put("applyType", 0);
            } else req.put("applyType", 1);

            List<Map<String, Object>> ticketTokens = new ArrayList<>();

            Map<String, Object> tk = new HashMap<>();
            tk.put("flightInfoId", request.ticketSearchParam.ticketTokens.get(0).flightInfoId);
            tk.put("priceInfoId", request.ticketSearchParam.ticketTokens.get(0).priceInfoId);
            tk.put("productType", "");

            ticketTokens.add(tk);

            req.put("ticketTokens", ticketTokens);


            strRequestData = JSON.toJSONString(req);
            strResponseData = HttpClientUtil.doPostJson(url, strRequestData);
            // 验价实体处理
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);

            if (fsResponse.code != 1) {
                response.ErrorMsg = fsResponse.msg;
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }

            JSONObject jsonObject = (JSONObject) fsResponse.data;
            HangChangeFlight hangChangeFlight = JSON.toJavaObject(jsonObject, HangChangeFlight.class);

            response.context = hangChangeFlight.context;
            MoChangeConfirmFeedetail feeDetail = new MoChangeConfirmFeedetail();
            feeDetail.rerouteFee = new Double(hangChangeFlight.feeDetail.changeFee).toString();
            feeDetail.ticketDiffPrice = new Double(hangChangeFlight.feeDetail.ticketDiffPrice).toString();
            feeDetail.totalPayPrice = new Double(hangChangeFlight.feeDetail.totalPayPrice).toString();
            response.feeDetail = feeDetail;
            //foreach(var )
            //todo
            response.IsSuccess = true;


        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }
        return response;
    }

    //提交改期申请
    @Override
    public MoOrderChangeResponse orderChange(MoOrderChangeRequest request) {
        MoOrderChangeResponse response = new MoOrderChangeResponse();
        response.RequestType = EnumHelper.RequestType.HangBanGuanJia;
        response.OnlyCode = request.OnlyCode;

        String strRequestData = "";
        String strResponseData = "";
        String url = "";
        try {
            url = ip + "order/change/submit?access_token=" + getToken();

            String strPsgId = "";
            for (ChangePassenger p : request.ChangePassenger)
                strPsgId += p.Id + ",";
            strPsgId = strPsgId.substring(0, strPsgId.length() - 1);

            int rerouteType = 1;
            if (request.IsFree) rerouteType = 1;
            else rerouteType = 0;

            Map<String, Object> requstHeadBody = new HashMap<>();

            requstHeadBody.put("orderId", request.OrderId);
            requstHeadBody.put("ticketIds", strPsgId);
            requstHeadBody.put("context", request.ProductID);
            requstHeadBody.put("applyType", rerouteType);

            strRequestData = JSON.toJSONString(requstHeadBody);

            strResponseData = HttpClientUtil.doPostJson(url, strRequestData);
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);

            if (fsResponse.code != 1) {
                response.ErrorMsg = fsResponse.msg;
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }

            JSONObject jsonObject = (JSONObject) fsResponse.data;

            if (jsonObject.getIntValue("status") == 0) {
                response.ErrorMsg = jsonObject.getString("content");
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }

            response.ApplicationId = jsonObject.getString("orderId");

            response.IsSuccess = true;
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }
        return response;
    }

    //上传退改证明材料
    public HangResponse attachUplod(MultipartFile[] multipartFiles) {
        HangResponse response = new HangResponse();

        String strRequestData = "";
        String strResponseData = "";
        String url = "";
        try {
            List<MoFile> ListMoFile = new ArrayList<>();
            for (MultipartFile item : multipartFiles) {
                MoFile moFile = new MoFile();
                moFile.Name = item.getOriginalFilename();
                moFile.Content = item.getBytes();
                ListMoFile.add(moFile);
            }

            url = ip + "order/attachment/upload?access_token=" + getToken();

            String boundary = "----WebKitFormBoundaryuyOmIphCywIpCJX5";//随机分割线
            byte[] UploadBuffers = null;
            StringBuilder UploadBuf = new StringBuilder();

            for(MoFile bb : ListMoFile)
            {

                UploadBuf = new StringBuilder();

                UploadBuf.append("\r\n");

                UploadBuf.append(boundary + "\r\n");
                UploadBuf.append("Content-Disposition: form-data; name=\"files\"; filename=\""+bb.Name+"\"");
                UploadBuf.append("\r\n");
                UploadBuf.append("Content-Type: image/"+bb.Name.substring(bb.Name.indexOf(".") + 1)+"\r\n\r\n");
                byte[] HeadBytes = UploadBuf.toString().getBytes();

                UploadBuffers = composeArrays(UploadBuffers, HeadBytes);
                UploadBuffers = composeArrays(UploadBuffers, bb.Content);
            }

            UploadBuf = new StringBuilder();
            UploadBuf.append("\r\n" + boundary + "--");//尾部追加分割线
            byte[] TailBytes = UploadBuf.toString().getBytes();
            UploadBuffers = composeArrays(UploadBuffers, TailBytes);

            strResponseData = HttpClientUtil._PostUrlHtml(url, UploadBuffers,"multipart/form-data;boundary=" + boundary.substring(2), false, "");
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);

            return fsResponse;
        } catch (Exception ex) {
            return response;
        }
    }

    private byte[] composeArrays(byte[] b1, byte[] b2)
    {
        if (b1 == null)
        {
            return b2;
        }
        else
        {
            byte[] b3 = new byte[b1.length + b2.length];
            for (int i = 0; i < b1.length; i++) {
                b3[i] = b1[i];
            }
            for (int i = b1.length; i < b3.length; i++) {
                b3[i] = b2[i - b1.length];
            }
            return b3;
        }
    }

    //提交退改证明材料
    @Override
    public MoAttachmentResponse addAttachment(MoAttachmentRequest request) {
        MoAttachmentResponse response = new MoAttachmentResponse();

        response.RequestType = EnumHelper.RequestType.HangBanGuanJia;
        response.OnlyCode = request.OnlyCode;

        String strRequestData = "";
        String strResponseData = "";

        String url = "";
        try
        {
            HangResponse upres = attachUplod(request.multipartFiles);

            if (upres.code != 1)
            {
                response.ErrorMsg = "预上传文件接口报错：" + upres.msg;
            }
            JSONObject jsonObject = (JSONObject)upres.data;
            String json = jsonObject.getString("attachUrl");
            List<String> attachUrls = JSONObject.parseArray(json, String.class);

            Map<String, Object> req = new HashMap<>();

            req.put("orderId", request.OrderId);
            req.put("type", request.ApplyType);

            List<Map<String, Object>> attachList = new ArrayList<>();
            for (String pid : request.ApplyId.split(","))
            {
                Map<String, Object> ss = new HashMap<>();
                ss.put("ticketId", pid);
                ss.put("attachUrls", attachUrls);

                attachList.add(ss);
            }
            req.put("attachList", attachList);

            url = ip + "order/attachment/submit?access_token=" + getToken();


            strRequestData = JSON.toJSONString(req);

            strResponseData = HttpClientUtil.doPostJson(url, strRequestData);
            HangResponse fsResponse = JSONObject.parseObject(strResponseData, HangResponse.class);

            if (fsResponse.code != 1)
            {
                response.ErrorMsg = fsResponse.msg;
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                return response;
            }

            response.IsSuccess = true;

        }
        catch (Exception ex)
        {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        }
        return response;
    }




    public HangResponse postHangResponse(String url, String json) {
        String data = HttpClientUtil.doPostJson(url, json);

        HangResponse hangResponse = JSONObject.parseObject(data, HangResponse.class);
        if (!hangResponse.msg.equals("success")) {
            throw new ParamException(hangResponse.msg);
        }
        return hangResponse;
    }

    /**
     * 根据机场三字码获取机场名称
     *
     * @return
     */
    private String getAirPortNameByRirPortCode(String airPortCode) {
        if (airportService == null) {
            return airPortCode;
        }
        Airport airport = airportService.getAirPortNameByRirPortCode(airPortCode);
        return airport.getAirnamesort();
    }
}
